home *** CD-ROM | disk | FTP | other *** search
/ Gigarom 1 / Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso / FILES / DEV / A-B / 004.TubeTest.cpt / TubeTest.c < prev    next >
C/C++ Source or Header  |  1988-08-01  |  14KB  |  463 lines

  1. /*------------------------------------------------------------------------------
  2. #
  3. #    Macintosh Developer Technical Support
  4. #
  5. #    Simple Color QuickDraw Animation Sample Application
  6. #
  7. #    TubeTest
  8. #
  9. #    TubeTest.p    -    Pascal Source
  10. #
  11. #    Copyright © 1988 Apple Computer, Inc.
  12. #    All rights reserved.
  13. #
  14. #    Versions:    1.0                    8/88
  15. #
  16. #    Components:    TubeTest.p            August 1, 1988
  17. #                TubeTest.c            August 1, 1988
  18. #                TubeTest.r            August 1, 1988
  19. #                PTubeTest.make        August 1, 1988
  20. #                CTubeTest.make        August 1, 1988
  21. #
  22. #    The TubeTest program is a simple demonstration of how to use the Palette 
  23. #    Manager in a color program.  It has a special color palette that is associated
  24. #    with the main window.  The colors are animated using the Palette Manager 
  25. #    to give a flowing tube effect.  The program is very simple, and the Palette
  26. #    Manager and drawing parts are put in separate subroutines to make it easier
  27. #    to figure out what is happening.
  28. #    
  29. #    The program is still a complete Macintosh application with a Main Event Loop,
  30. #    so there is the extra code to run the MEL.  
  31. #    
  32. #    There is a resource file that is necessary as well, to define the Menus, Window,
  33. #    Dialog, and Palette resources used in the program.  
  34. #
  35. #    See Sample and TESample for the general structure and MultiFinder techniques that
  36. #    we recommend that you use when building a new application.
  37. #
  38. ------------------------------------------------------------------------------*/
  39.  
  40.  /*
  41.     File TubeTest.c
  42.  
  43.     Version 1.0:  6/2/88
  44.                  7/20/88    DJB    Converted to C (MPW 3.0 ONLY)
  45.     
  46.     4/19/88:
  47.     TubeTest -- A small sample application written by Bo3b Johnson.
  48.     The idea is to draw two circles in varying colors in the window, then
  49.     animate the colors when the menu is chosen.    This is a complete program
  50.     with event loop and everything.    It is intended to be a simple example of
  51.     how to use the Palette Manager to do some minor color animation, and
  52.     how to use the PM to set up the colors desired in a window.
  53.     
  54.     Also see the resource file that goes with this to see how the Palette 
  55.     itself is layed out.
  56.     
  57.     Could be built with something like this:
  58.         rez TubeTest.r -o TubeTest
  59.         C -r TubeTest.C
  60.         Link TubeTest.c.o ∂
  61.             "{Libraries}"Interface.o ∂
  62.             "{CLibraries}"CRuntime.o ∂
  63.             "{CLibraries}"CInterface.o ∂
  64.             -o CTubeTest
  65.         CTubeTest
  66.  */
  67.  
  68. /* Where does it fit:
  69.     This is a series of sample programs for those doing development
  70.     using Color QuickDraw.  Since the whole color problem depends
  71.     upon the exact effect desired, there are a number of answers
  72.     to how to use colors, from the simple to the radically complex.
  73.     These programs try to cover the gamut, so you should use 
  74.     which ever seems appropriate.  In most cases, use the simplest
  75.     one that will give the desired results.  The compatibility
  76.     rating is from 0..9 where low is better.  The more known risks 
  77.     there are the higher the rating.
  78.     
  79.     
  80.     The programs (in order of compatibility):
  81.     
  82.         SillyBalls:
  83.             This is the simplest use of Color QuickDraw, and does
  84.             not use the Palette Manager.  It draws randomly colored
  85.             balls in a color window.  This is intended to give you
  86.             the absolute minimum required to get color on the screen.
  87.             Written in straight Pascal code.
  88.             Compatibility rating = 0, no known risks.
  89.         
  90.         FracAppPalette:
  91.             This is a version of FracApp that uses only the Palette
  92.             Manager.  It does not support color table animation
  93.             since that part of the Palette Manager is not sufficient.
  94.             The program demonstrates a full color palette that is
  95.             used to display the Mandelbrot set.  It uses an offscreen
  96.             gDevice w/ Port to handle the data, using CopyBits to
  97.             draw to the window.  The Palette is automatically 
  98.             associated with each window.  The PICT files are read
  99.             and written using the bottlenecks, to save on memory
  100.             useage.
  101.             Written in MacApp Object Pascal code.
  102.             Compatibility rating = 0, no known risks.
  103.         
  104.         TubeTest:    (***)
  105.             This is a small demo program that demonstrates using the
  106.             Palette Manager for color table animation.  It uses a 
  107.             color palette with animating entries, and draws using the
  108.             Palette Manager.  There are two circles of animating colors
  109.             which gives a flowing tube effect.  This is a valid case
  110.             for using the animating colors aspect of the Palette Manager,
  111.             since the image is being drawn directly.
  112.             Written in straight Pascal code.
  113.             Compatibility rating = 0, no known risks.
  114.         
  115.         FracApp:
  116.             This is the ‘commercial quality’ version of FracApp.  This
  117.             version supports color table animation, using an offscreen
  118.             gDevice w/ Port, and handles multiple documents.  The
  119.             CopyBits updates to the screen are as fast as possible.  The
  120.             program does not use the Palette Manager, except to
  121.             provide for the system palette, or color modes with less than
  122.             255 colors.  For color table animation using an offscreen
  123.             gDevice w/ Port, it uses the Color Manager and handles the
  124.             colors itself.  Strict compatibility was relaxed to allow for
  125.             a higher performance program.  This is the most ‘real’ of the
  126.             sample programs.
  127.             Written in MacApp Object Pascal code.
  128.             Compatibility rating = 2.  (nothing will break, but it may not
  129.                 always look correct.)
  130.         
  131.         FracApp300:
  132.             This doesn't support colors, but demonstrates how to create and
  133.             use a 300 dpi bitmap w/ Port.  The bitmap is printed at full
  134.             resolution on LaserWriters, and clipped on other printers (but
  135.             they still print).  It demonstrates how to use a high resolution
  136.             image as a PICT file, and how to print them out.
  137.             Written in MacApp Object Pascal code.
  138.             Compatibility rating = 1.  (The use of PrGeneral is slightly 
  139.                 out of the ordinary, although supported.)
  140. */
  141.  
  142.  
  143. #include <Types.h>
  144. #include <Memory.h>
  145. #include <Quickdraw.h>
  146. #include <Palette.h>
  147. #include <Fonts.h>
  148. #include <Events.h>
  149. #include <Menus.h>
  150. #include <Windows.h>
  151. #include <TextEdit.h>
  152. #include <Dialogs.h>
  153. #include <Desk.h>
  154. #include <OSUtils.h>
  155. #include <ToolUtils.h>
  156. #include <SegLoad.h>
  157.     
  158. /* Constants */
  159. #define appleID                1000            /* resource IDs/menu IDs for Apple, */
  160. #define fileID                1001            /*     File and */
  161. #define editID                1002            /*    Edit menus */
  162.     
  163. #define appleM                0                /* Index for each menu in myMenus (array of menu handles) */
  164. #define fileM                1
  165. #define editM                2
  166.  
  167. #define menuCount            3                /* Total number of menus */
  168.  
  169. #define windowID            1000            /* Resource ID for main window */
  170. #define aboutMeDLOG         1000            /* And Resource ID for About box dialog. */
  171.  
  172. #define tubularItem            1                /* When checked, animation of colors. */
  173. #define quitItem            3                /* Quit in the menu of course. */
  174.  
  175. #define aboutMeCommand        1                /* Menu item in apple menu for About TubeTest item */
  176.     
  177. #define totalColors            152                /* use 150 colors in our palette for drawing eyes. */
  178. #define numColors            150                /* to skip black and white. */
  179.     
  180.     
  181. /* Globals */
  182. MenuHandle    myMenus[menuCount];
  183. Rect        dragRect;                        /* Rectangle used to mark bounds for dragging window */
  184. Boolean        doneFlag,                        /* true if user has chosen Quit command */
  185.             tubeCheck;                        /* if true, the menu is checked, and we animate. */
  186. EventRecord    myEvent;
  187. WindowPtr    myWindow,
  188.             whichWindow;
  189. char        theChar;
  190. OSErr        error;
  191. SysEnvRec    theWorld;
  192.  
  193. /* Prototypes */
  194. void DrawEyes();
  195. void SetUpMenus();
  196. void ShiftyColors();
  197. void ShowAboutMeDialog();
  198. void DoCommand(long int mResult);
  199.  
  200.  
  201. /* Make the 2.0 Interface for passing Points to the Toolbox by address,
  202.    emulate the 3.0 method of passing Points by value. This list only contains
  203.    the affected routines actually used in this sample, and is not intended to
  204.    be a comprehensive list of the affected routines. */
  205. #ifndef MPW3
  206. #    define FindWindow    FINDWINDOW
  207. #    define MenuSelect    MENUSELECT
  208. pascal void Debugger()
  209.     extern 0xA9FF;
  210. #endif
  211.  
  212.     
  213. main()
  214. {
  215.     /*
  216.     **    Test the computer to be sure we can do color.  
  217.     **    If not we would crash, which would be bad.  
  218.     **    If we can’t run, just beep and exit.
  219.     */
  220.     error = SysEnvirons(1, &theWorld);
  221.     if (theWorld.hasColorQD == false) {
  222.         SysBeep (50);
  223.         ExitToShell();                            /* If no color QD, we must leave. */
  224.     };
  225.  
  226.     InitGraf(&qd.thePort);
  227.     InitFonts();
  228.     InitWindows();
  229.     InitMenus();
  230.     TEInit();
  231.     InitDialogs(nil);
  232.     InitCursor();
  233.  
  234.     SetRect(&dragRect, 4, 24, qd.screenBits.bounds.right - 4, qd.screenBits.bounds.bottom - 4);
  235.     doneFlag = false;                            /* flag to detect when Quit command is chosen */
  236.     tubeCheck = false;                            /* flag for animating color is initially off. */
  237.  
  238.     /*
  239.     **    Open the color window.
  240.     */
  241.     myWindow = GetNewCWindow(windowID, nil, (Ptr) -1);
  242.     SetPort(myWindow);
  243.  
  244.     /*
  245.     **    Set up menus last, since the menu drawing can then use 
  246.     **    the palette we have for our window. 
  247.     **    Makes the Apple look better, in particular.
  248.     */
  249.     SetUpMenus();
  250.     
  251.     /*
  252.     **    Main Event Loop
  253.     */
  254.     do {
  255.         SystemTask();
  256.  
  257.         if (GetNextEvent(everyEvent, &myEvent)) {
  258.             switch (myEvent.what) {                /* case on event type */
  259.  
  260.                 case mouseDown:
  261.                     switch (FindWindow(myEvent.where, &whichWindow)) {
  262.  
  263.                         case inSysWindow:        /* desk accessory window: call Desk Manager to handle it */
  264.                             SystemClick(&myEvent, whichWindow);
  265.                             break;
  266.  
  267.                         case inMenuBar:            /* Menu bar: learn which command, then execute it. */
  268.                             DoCommand(MenuSelect(myEvent.where));
  269.                             break;
  270.  
  271.                         case inDrag:            /* title bar: call Window Manager to drag */
  272.                             DragWindow(whichWindow, myEvent.where, &dragRect);
  273.                             break;
  274.  
  275.                         case inContent:            /* body of application window: */
  276.                             if (whichWindow != FrontWindow())
  277.                                 SelectWindow(whichWindow); /* and make it active if not */
  278.                             break;
  279.                     }
  280.                     break;
  281.  
  282.                 case updateEvt:                    /* Update the eyes in window. */
  283.                     if ((WindowPtr) myEvent.message == myWindow) {
  284.                         BeginUpdate((WindowPtr) myEvent.message);
  285.                         DrawEyes();
  286.                         EndUpdate((WindowPtr) myEvent.message);
  287.                     }
  288.                     break;
  289.                             
  290.                 case keyDown:
  291.                 case autoKey:                    /* key pressed once or held down to repeat */
  292.                     if (myWindow == FrontWindow()) {
  293.                         theChar = (myEvent.message & charCodeMask); /* get the char */
  294.                         /* 
  295.                         **    If Command key down, do it as a Menu Command.
  296.                         */
  297.                         if (myEvent.modifiers & cmdKey)
  298.                             DoCommand(MenuKey(theChar));
  299.                     }
  300.                     break;
  301.  
  302.             }
  303.         }
  304.  
  305.         /*    
  306.         **    If we have menu item checked, go ahead and animate colors.
  307.         */
  308.         if (tubeCheck) ShiftyColors();
  309.         
  310.     } while (!doneFlag);
  311.  
  312.     /*
  313.     **    clean up after palette manager, 
  314.     **    so he can chuck the palette in use.
  315.     */
  316.     DisposeWindow (myWindow);
  317. }
  318.  
  319. /*
  320. **    This routine will update the window when required by update events.    It
  321. **    will draw two circular dudes that are indexed in colors through the colors
  322. **    we are using. 0 and 1 are skipped, since those are white and black in the
  323. **    palette.
  324. */
  325. void DrawEyes()
  326. {
  327.     Rect    tempRect;
  328.     int        i;
  329.     
  330.     SetRect(&tempRect, numColors, numColors, numColors, numColors);
  331.     for (i = 2; i <= totalColors; i++) {
  332.         PmForeColor(i);
  333.         FrameOval (&tempRect);
  334.         InsetRect (&tempRect, -1, -1);
  335.     }
  336.     
  337.     SetRect(&tempRect, numColors*3, numColors, numColors*3, numColors);
  338.     for (i = totalColors; i >= 2; i--) {
  339.         PmForeColor(i);
  340.         FrameOval (&tempRect);
  341.         InsetRect (&tempRect, -1, -1);
  342.     }
  343. }
  344.  
  345.  
  346. /*
  347. **    Read menu descriptions from resource file into memory 
  348. **    and store handles in myMenus array.
  349. **    Insert into MenuBar and draw.
  350. */
  351. void SetUpMenus()
  352. {
  353.     int i;
  354.  
  355.     myMenus[appleM] = GetMenu(appleID);         /* read Apple menu from resource file */
  356.     AddResMenu(myMenus[appleM], 'DRVR');        /* add desk accessory names to Apple menu */
  357.     myMenus[fileM] = GetMenu(fileID);            /* read file menu from resource file */
  358.     myMenus[editM] = GetMenu(editID);            /* read edit menu from resource file */
  359.  
  360.     for (i = 0; i < menuCount; i++) 
  361.         InsertMenu(myMenus[i], 0);                 /* install menus in menu bar */
  362.     
  363.     DrawMenuBar();                                /* and draw menu bar */
  364. }
  365.  
  366.  
  367. /*
  368. **    Use the Palette currently attached to the main window to animate the colors 
  369. **    in the circular eye shapes.  This will rotate them around to give the flowing 
  370. **    tube effect. We make the palette into a color table so we can move entries 
  371. **    around.    We have to skip the first two entries since those are black and white. 
  372. **    (entries 0 and 1)
  373. */
  374. void ShiftyColors()
  375. {
  376.     
  377.     PaletteHandle    currPalette;
  378.     CTabHandle        destCTab;
  379.     ColorSpec        lastCSpec;
  380.     
  381.     SetPort (myWindow);
  382.     
  383.     currPalette = GetPalette(myWindow);
  384.     destCTab = (CTabHandle) NewHandle(sizeof(ColorTable)+(totalColors*sizeof(ColorSpec)));
  385.     if (destCTab == nil)  return;
  386.     Palette2CTab(currPalette, destCTab);
  387.     
  388.     /*
  389.     **    Move the colors around in the color table, skipping 0 and 1, and moving
  390.     **    all the elements down by one, and copying the element at 2 back to the 
  391.     **    end of the table. The effect is to rotate the colors in the table.
  392.     */
  393.     lastCSpec = (*destCTab)->ctTable[2];                        /* pull first one off. */
  394.     BlockMove (&(*destCTab)->ctTable[3], 
  395.                &(*destCTab)->ctTable[2], 
  396.                (numColors) * sizeof(ColorSpec) );                /* copy all one entry down. */
  397.     (*destCTab)->ctTable[totalColors-1] = lastCSpec;            /* put last color back on front. */
  398.         
  399.     AnimatePalette(myWindow, destCTab, 2, 2, numColors);
  400.     
  401.     DisposHandle ((Handle) destCTab);
  402. }
  403.  
  404.  
  405. /*    
  406. **    Display the dialog box in response to the 'About TubeTest' menu item
  407. */
  408. void ShowAboutMeDialog()
  409. {
  410.     DialogPtr    theDialog;
  411.     short        itemHit;
  412.  
  413.     theDialog = GetNewDialog(aboutMeDLOG, nil, (WindowPtr) -1);
  414.     ModalDialog(nil, &itemHit);
  415.     DisposDialog(theDialog);
  416. }
  417.  
  418.  
  419. /*
  420. **    Execute menu command specified by mResult,
  421. **    the result of MenuSelect
  422. */
  423. void DoCommand(long int mResult)
  424. {
  425.     short    theItem,                            /* menu item number from mResult low-order word */
  426.             theMenu;                            /* menu number from mResult high-order word */
  427.     Str255    name;                                /* desk accessory name */
  428.     int        temp;
  429.     Boolean    dummy;
  430.  
  431.     theItem = LoWord(mResult);                    /* call Toolbox Utility routines to */
  432.     theMenu = HiWord(mResult);                    /* set menu item number and menu */
  433.  
  434.     switch (theMenu) {                            /* switch on menu ID */
  435.  
  436.         case appleID:
  437.             if (theItem == aboutMeCommand)
  438.                 ShowAboutMeDialog();
  439.             else {
  440.                     GetItem(myMenus[appleM], theItem, name);
  441.                     temp = OpenDeskAcc(name);
  442.                     SetPort(myWindow);
  443.             }
  444.             break;
  445.  
  446.         case fileID:
  447.             if (theItem == quitItem)
  448.                 doneFlag = true;
  449.             else if (theItem = tubularItem) {
  450.                     tubeCheck = !tubeCheck;
  451.                     CheckItem(myMenus[fileM], tubularItem, tubeCheck);
  452.             }
  453.             break;
  454.  
  455.         case editID:
  456.             dummy = SystemEdit(theItem - 1);    /* Pass the command on to the Desk Manager. */
  457.             break;
  458.     }
  459.  
  460.     HiliteMenu(0);                                /* Unhighlight menu title */
  461.                                                 /* (highlighted by MenuSelect) */
  462. }
  463.